#include "sensortcpserver.h"

nlohmann::json SensorTCPServer::parse_command(const std::string& cmd_str)
{
	try {
		return nlohmann::json::parse(cmd_str);
	}
	catch (const nlohmann::json::parse_error& e) {
		nlohmann::json err;
		err["status"] = "error";
		err["msg"] = "指令格式错误（非JSON）：" + std::string(e.what());
		return err;
	}
}

nlohmann::json SensorTCPServer::handle_command(const nlohmann::json& cmd)
{
	nlohmann::json response;
	if (!cmd.contains("cmd")) {
		response["status"] = "error";
		response["msg"] = "缺少 cmd 字段（支持：connect/start/stop/status）";
		return response;
	}

	std::string cmd_type = cmd["cmd"];
	// 1. 连接传感器
	if (cmd_type == "connect") {
		sensor_collection.connect();
		response["status"] = "success";
		response["msg"] = "传感器连接完成";
		response["connected_sensors"] = sensor_collection.get_enabled_sensors();
	}
	// 2. 启动定时器（支持自定义间隔）
	else if (cmd_type == "start") {
		int interval_ms = cmd.value("interval_ms", 100);
		 sensor_collection.start_mm_timer(interval_ms);
		response["status"] = "success";
		response["msg"] = "定时器启动（间隔：" + std::to_string(interval_ms) + "ms）";
	}
	// 3. 停止定时器
	else if (cmd_type == "stop") {
		 sensor_collection.stop_mm_timer();
		response["status"] = "success";
		response["msg"] = "定时器已停止";
	}
	// 4. 查询状态
	else if (cmd_type == "status") {
		response["status"] = "success";
		 response["is_timer_running"] = sensor_collection.is_timer_running();
		 response["connected_sensors"] = sensor_collection.get_enabled_sensors();
	}
	// 未知指令
	else {
		response["status"] = "error";
		response["msg"] = "未知指令：" + cmd_type;
	}
	return response;
}

void SensorTCPServer::handle_client(boost::asio::ip::tcp::socket& client)
{
	std::string ip = client.remote_endpoint().address().to_string();
	log("Python 客户端已连接：" + ip);

	try {
		while (is_running) {
			boost::asio::streambuf buf;
			boost::system::error_code ec;

			size_t bytes_read = boost::asio::read_until(client, buf, '\n', ec);

			if (ec) {
				if (ec == boost::asio::error::eof) {
					log("客户端断开连接：" + ip);
				}
				else {
					log("读取指令失败：" + ec.message());
				}
				break;
			}

			// 2. 提取指令字符串（去掉换行符）
			std::istream is(&buf);
			std::string cmd_str;
			std::getline(is, cmd_str);
			log("收到指令：" + cmd_str);

			// 3. 处理指令并生成响应
			nlohmann::json cmd = parse_command(cmd_str);
			nlohmann::json response = handle_command(cmd);
			std::string response_str = response.dump() + "\n";  // 响应加换行符

			// 4. 同步发送响应
			boost::asio::write(client, boost::asio::buffer(response_str), ec);
			if (ec) {
				log("发送响应失败：" + ec.message());
				break;
			}
			log("发送响应：" + response_str.substr(0, response_str.size() - 1));  // 不打印换行符
		}
	}
	catch (const std::exception& e) {
		log("客户端处理异常：" + std::string(e.what()));
	}

	// 关闭客户端连接
	client.close();
	log("等待下一个客户端连接...");
}

void SensorTCPServer::load_config(const std::string& config_path)
{
	// 设置默认值（如果配置文件加载失败则使用）
	host = "127.0.0.1";
	port = 8888;

	try {
		// 加载YAML文件
		YAML::Node config = YAML::LoadFile(config_path);

		// 解析host（字符串类型）
		if (config["host"]) {
			host = config["host"].as<std::string>();  // 转换为字符串
			log("从配置文件加载host: " + host);
		}
		else {
			log("配置文件中未找到host，使用默认值: " + host);
		}

		// 解析port（整数类型）
		if (config["port"]) {
			port = config["port"].as<uint16_t>();  // 转换为16位整数
			log("从配置文件加载port: " + std::to_string(port));
		}
		else {
			log("配置文件中未找到port，使用默认值: " + std::to_string(port));
		}

	}
	catch (const YAML::BadFile& e) {
		// 文件不存在或无法打开
		log("配置文件不存在或无法打开（" + std::string(e.what()) + "），使用默认配置: host=" + host + ", port=" + std::to_string(port));
	}
	catch (const YAML::TypedBadConversion<uint16_t>& e) {
		// port类型错误（如不是整数）
		log("port类型错误（" + std::string(e.what()) + "），使用默认port: " + std::to_string(port));
	}
	catch (const std::exception& e) {
		// 其他未知错误
		log("加载配置失败（" + std::string(e.what()) + "），使用默认配置: host=" + host + ", port=" + std::to_string(port));
	}
}

void SensorTCPServer::start() {
	try {
		boost::asio::io_context io_context;
		// 初始化 acceptor（用 new 动态分配，避免栈对象生命周期问题）
		boost::asio::ip::address server_addr;
		try {
			server_addr = boost::asio::ip::make_address(host);  // 转换字符串为IP地址
		}
		catch (const boost::system::system_error& e) {
			// 若host无效（如格式错误），回退到默认地址
			log("无效的IP地址（" + host + "）：" + e.what() + "，使用默认地址127.0.0.1");
			server_addr = boost::asio::ip::make_address("127.0.0.1");
		}

		// 用配置的IP和端口初始化acceptor
		acceptor = new boost::asio::ip::tcp::acceptor(
			io_context,
			boost::asio::ip::tcp::endpoint(server_addr, port)  // 绑定配置的地址和端口
		);

		log("C++ 传感器服务端启动，监听 " + host + ":" + std::to_string(port));
		log("C++ 传感器服务端启动，监听端口：" + std::to_string(port));

		// 循环监听：接受新连接→处理客户端→回到监听
		while (is_running) {
			boost::asio::ip::tcp::socket client(io_context);
			// 接受连接（阻塞，但 stop() 关闭 acceptor 后会抛出异常）
			boost::system::error_code ec;
			acceptor->accept(client, ec);  // 用带 ec 的重载，避免直接抛异常

			if (ec) {
				if (is_running) {  // 非主动停止，才打印错误
					log("接受连接失败：" + ec.message());
				}
				continue;
			}

			// 处理当前客户端的指令
			handle_client(client);
		}
	}
	catch (const std::exception& e) {
		if (is_running) {
			log("服务端异常：" + std::string(e.what()));
		}
	}
	log("服务端已停止");
}

void SensorTCPServer::stop() {
	is_running = false;  // 先设为 false，让循环退出
	log("服务端开始停止...");

	// 1. 关闭 acceptor（强制 accept 退出阻塞）
	if (acceptor != nullptr) {
		boost::system::error_code ec;
		acceptor->close(ec);  // 关闭监听 socket
		if (ec) {
			log("关闭 acceptor 失败：" + ec.message());
		}
		else {
			log("acceptor 已关闭");
		}
	}

	// 2. 停止传感器定时器（确保采集停止）
	sensor_collection.stop_mm_timer();
	log("传感器定时器已停止");
}